package net.aiion.weave.impl.ui;

import java.util.ArrayList;
import java.util.Collection;

import net.aiion.weave.impl.ui.events.ValueChangedEventImpl;
import net.aiion.weave.spi.cards.annotations.Access;
import net.aiion.weave.spi.cards.annotations.Property;
import net.aiion.weave.spi.messaging.annotations.Receives;
import net.aiion.weave.spi.naming.annotations.Bound;
import net.aiion.weave.spi.ui.Field;
import net.aiion.weave.spi.ui.ValueMessage;
import net.aiion.weave.spi.ui.annotations.Binds;
import net.aiion.weave.spi.ui.events.ValueChangedListener;

public abstract class AbstractField extends AbstractComponent implements Field
{
    @Property(Access.READ_ONLY)
    @Binds("label")
    private String label;

    @Property(Access.READ_ONLY)
    @Binds("value")
    private String value;

    private Collection<ValueChangedListener> valueChangedListeners;

    public AbstractField() {
    }

    @Bound
    public void initializeComponent() {
        valueChangedListeners = new ArrayList<>();
    }

    @Override
    public void setLabel(final String aLabel) {
        label = aLabel;
    }

    @Override
    public String getLabel() {
        return label;
    }

    @Override
    public void setValue(final String aTextValue) {
        value = aTextValue;
    }

    @Override
    public String getValue() {
        return value;
    }

    @Receives("org.weaveframework.ui")
    public void updateValue(final ValueMessage aValueMessage) {
        final String oldValue = getValue();
        setValue(aValueMessage.getValue());
        notifyValueChangedListeners(oldValue, getValue());
    }

    @Override
    public void addListener(final ValueChangedListener aValueChangedListener) {
        valueChangedListeners.add(aValueChangedListener);
    }

    @Override
    public void removeListener(final ValueChangedListener aValueChangedListener) {
        valueChangedListeners.remove(aValueChangedListener);
    }

    private void notifyValueChangedListeners(final String aOldValue, final String aNewValue) {
        for (ValueChangedListener valueChangedListener : valueChangedListeners) {
            valueChangedListener.valueChanged(new ValueChangedEventImpl(aOldValue, aNewValue));
        }
    }
}
